﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using System.IO;
using System.Collections;

namespace 根据剖面线及路径建立模型
{
    public partial class Form1 : Form
    {
        Autodesk.AutoCAD.Interop.AcadApplication AcadApp;
        Autodesk.AutoCAD.Interop.AcadDocument AcadDoc;
        AcadRegion profileRegionObject;//定义选取剖面线后生成的面域对象
        double[] profileCoords;//剖面线上个节点坐标
        double Is2DOr3DPolyline;//记录剖面线为二维还是三维多段线,若为二维多段线则记录多段线高程值，若为三维多段线则值为3

        public Form1()
        {
            InitializeComponent();
        }

        private void 启动CAD()
        {
            try
            {
                AcadApp =
               (AcadApplication)System.Runtime.InteropServices.Marshal.GetActiveObject("AutoCAD.Application");
                AcadDoc = AcadApp.ActiveDocument;
            }
            catch
            {
                OpenFileDialog pOpenDG = new OpenFileDialog();
                pOpenDG.Filter = "CAD文件(*.dwg)|*.dwg|CAD图形文件(*.dxf)|*.dxf";
                pOpenDG.Title = "打开CAD文件";
                pOpenDG.ShowDialog();
                string filePath = pOpenDG.FileName;
                if (filePath == "")
                {
                    MessageBox.Show("选择CAD文件无效！", "文件无效！");
                    Application.Exit();
                }
                AcadApp = new AcadApplication();
                AcadDoc = AcadApp.Documents.Open(filePath, null, null);
            }
            AcadApp.Application.Visible = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            启动CAD();
        }

        private void 选取剖面线_Click(object sender, EventArgs e)
        {
            Microsoft.VisualBasic.Interaction.AppActivate(AcadApp.Caption);
            object returnObj, pickPoint;
            string pickPrompt = "选取剖面线对象!";
            AcadDoc.Utility.GetEntity(out returnObj, out pickPoint, pickPrompt);
            AcadObject returnCADObj = (AcadObject)returnObj;
            if (returnCADObj.ObjectName == "AcDb3dPolyline")
            {
                Acad3DPolyline return3dPolyLine = (Acad3DPolyline)returnCADObj;
                if (!return3dPolyLine.Closed)
                {
                    MessageBox.Show("选择的三维多段线不是封闭线段！请选择封闭线段！");
                    return;
                }
                Acad3DPolyline[] regionObjects = new Acad3DPolyline[1];
                regionObjects[0] = return3dPolyLine;
                object[] regionObject;
                regionObject = (object[])AcadDoc.ModelSpace.AddRegion(regionObjects);
                profileRegionObject = (AcadRegion)(regionObject[0]);

                profileCoords = (double[])return3dPolyLine.Coordinates;
                Is2DOr3DPolyline = 3;
                for (int i = 0; i < profileCoords.Length / 3; i++)
                {
                    profileBasePointComboBox.Items.Add(i + 1);
                }
                profileBasePointComboBox.Text = "1";
            }
            else if (returnCADObj.ObjectName == "AcDbPolyline")
            {
                AcadLWPolyline returnPolyLine = (AcadLWPolyline)returnCADObj;
                if (!returnPolyLine.Closed)
                {
                    MessageBox.Show("选择的多段线不是封闭线段！请选择封闭线段！");
                    return;
                }
                AcadLWPolyline[] regionObjects = new AcadLWPolyline[1];
                regionObjects[0] = returnPolyLine;
                object[] regionObject;
                regionObject = (object[])AcadDoc.ModelSpace.AddRegion(regionObjects);
                profileRegionObject = (AcadRegion)(regionObject[0]);

                profileCoords = (double[])returnPolyLine.Coordinates;
                Is2DOr3DPolyline = returnPolyLine.Elevation;
                for (int i = 0; i < profileCoords.Length / 2; i++)
                {
                    profileBasePointComboBox.Items.Add(i + 1);
                }
                profileBasePointComboBox.Text = "1";
            }

            if (deleteProfileCheckBox.Checked)
            {
                returnCADObj.Delete();
            }
        }

        private void 选取路径对象_Click(object sender, EventArgs e)
        {
            Microsoft.VisualBasic.Interaction.AppActivate(AcadApp.Caption);
            object returnObj, pickPoint;
            string pickPrompt = "选取路径对象!";
            AcadDoc.Utility.GetEntity(out returnObj, out pickPoint, pickPrompt);
            AcadObject returnCADObj = (AcadObject)returnObj;
            if (returnCADObj.ObjectName == "AcDb3dPolyline")
            {
                Acad3DPolyline returnPolyLine = (Acad3DPolyline)returnCADObj;
                //移动面域对象
                double[] moveFromPoint = new double[3], moveToPoint = new double[3];
                int basePointIndex;
                basePointIndex = Int16.Parse(profileBasePointComboBox.Text) - 1;
                if (Is2DOr3DPolyline == 3)
                {
                    moveFromPoint[0] = profileCoords[3 * basePointIndex];
                    moveFromPoint[1] = profileCoords[3 * basePointIndex + 1];
                    moveFromPoint[2] = profileCoords[3 * basePointIndex + 2];
                }
                else
                {
                    moveFromPoint[0] = profileCoords[2 * basePointIndex];
                    moveFromPoint[1] = profileCoords[2 * basePointIndex + 1];
                    moveFromPoint[2] = Is2DOr3DPolyline;
                }
                double[] pathCoords;
                double rotateAngle = 0.0;
                pathCoords = (double[])returnPolyLine.Coordinates;
                if (baseOnPathStartRadioButton.Checked)
                {
                    moveToPoint[0] = pathCoords[0];
                    moveToPoint[1] = pathCoords[1];
                    moveToPoint[2] = pathCoords[2];
                    rotateAngle = -Math.Atan((pathCoords[3] - pathCoords[0]) / (pathCoords[4] -
                   pathCoords[1]));
                }
                else if (baseOnPathEndRadioButton.Checked)
                {
                    moveToPoint[0] = pathCoords[pathCoords.Length - 3];
                    moveToPoint[1] = pathCoords[pathCoords.Length - 2];
                    moveToPoint[2] = pathCoords[pathCoords.Length - 1];
                    rotateAngle = -Math.Atan((pathCoords[pathCoords.Length - 3] -
                   pathCoords[pathCoords.Length - 6]) / (pathCoords[pathCoords.Length - 2] -
                   pathCoords[pathCoords.Length - 5]));
                }
                profileRegionObject.Move(moveFromPoint, moveToPoint);
                double[] rotatePoint2 = new double[3];
                rotatePoint2[0] = moveToPoint[0] - 10;
                rotatePoint2[1] = moveToPoint[1];
                rotatePoint2[2] = moveToPoint[2];
                //旋转面域对象
                profileRegionObject.Rotate3D(moveToPoint, rotatePoint2, -Math.PI / 2);
                profileRegionObject.Rotate(moveToPoint, rotateAngle);
                AcadDoc.ModelSpace.AddExtrudedSolidAlongPath(profileRegionObject, returnPolyLine);
                profileRegionObject.Delete();
                if (deletePathCheckBox.Checked)
                {
                    returnPolyLine.Delete();
                }
            }
            else
            {
                MessageBox.Show("选取对象不是三维多段线！路径必须为三维多段线！");
            }
        }
    }
}
